/******************************************************************************
 * Copyright (C) 2025 COMPANY or its affiliates.
 * 
 * All Rights Reserved.
 * 
 @file system.c
 * 
 @par dependencies 
 - system.h  // 对应头文件
 * 
 @author liubin | R&D Dept. | COMPANY
 * 
 @brief 模块核心功能实现，包括：
            - 功能点1：xxx初始化与配置
            - 功能点2：xxx数据处理与交互
            - 功能点3：xxx资源管理与释放
 * 
 Processing flow:
 * 1. 初始化阶段：
            - 调用xxx_init()完成硬件/软件初始化
            - 初始化全局变量与静态变量
            - 注册回调函数（如需要）
 * 2. 运行阶段：
            - 接收输入数据（如xxx_rx()）
            - 调用核心处理函数（如xxx_process()）
            - 输出处理结果（如xxx_tx()）
 * 3. 销毁阶段：
            - 调用xxx_deinit()释放资源
            - 重置变量状态（如需要）
 * 
 @version V1.0 2025-11-09
 *
 @note 1 tab == 4 spaces!
 *       - 实现说明：如使用DMA传输、中断优先级配置
 *       - 性能限制：如最大处理速率、内存占用上限
 *       - 调试提示：关键日志输出位置、断点设置建议
 *
 *****************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "system.h"

#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_flash.h"

#include "bsp_flash.h"

#include "W25qxx.h"
/* Private typedef -----------------------------------------------------------*/
// 全局系统配置变量
static system_config_t g_system_config = {0};

/* Private define ------------------------------------------------------------*/

// 系统配置存储地址 (Flash最后4KB扇区)
//#define SYSTEM_CONFIG_ADDR      0x0807F000  // 根据你的STM32F411 Flash大小调整
//#define SYSTEM_CONFIG_SECTOR    FLASH_SECTOR_7
#define SYSTEM_CONFIG_ADDR      0  // 根据你的STM32F411 Flash大小调整
#define SYSTEM_CONFIG_SECTOR    FLASH_SECTOR_7
/* Private macro -------------------------------------------------------------*/


/* Private variables ---------------------------------------------------------*/


/* Global variables ----------------------------------------------------------*/


/* Private function prototypes -----------------------------------------------*/
static uint32_t system_config_calculate_crc32(system_config_t *config);

/* Global function prototypes -------------------------------------------------*/


/* Private functions ---------------------------------------------------------*/
/**
 * @brief 计算CRC32校验值 (简化版本)
 * @param config: 配置结构体指针
 * @return CRC32校验值
 */
static uint32_t system_config_calculate_crc32(system_config_t *config)
{
    uint32_t crc = 0xFFFFFFFF;
    uint8_t *data = (uint8_t *)config;
    uint32_t length = sizeof(system_config_t) - sizeof(uint32_t); // 不包括CRC字段本身
    
    // 简化的CRC32计算 (实际应用中建议使用硬件CRC或标准CRC32算法)
    for (uint32_t i = 0; i < length; i++)
    {
        crc ^= data[i];
        for (int j = 0; j < 8; j++)
        {
            if (crc & 1)
                crc = (crc >> 1) ^ 0xEDB88320;
            else
                crc = crc >> 1;
        }
    }
    return crc ^ 0xFFFFFFFF;
}

/**
 * @brief 验证CRC32校验值
 * @param config: 配置结构体指针
 * @return 0:校验成功 1:校验失败
 */
static uint8_t system_config_verify_crc32(system_config_t *config)
{
    uint32_t calculated_crc = system_config_calculate_crc32(config);
    return (calculated_crc == config->crc32) ? 0 : 1;
}

/* Exported functions --------------------------------------------------------*/

/**
 * @brief 系统配置初始化
 */
void system_config_init(void)
{
    // 尝试从Flash读取配置
    if (system_config_read(&g_system_config) != 0)
    {
        // 读取失败，初始化默认配置
        g_system_config.status.app_update_status = APP_UPDATE_STATUS_NO_UPDATE;
        g_system_config.ota_new_app_size = 0;
        g_system_config.current_app_size = 0;
        g_system_config.crc32 = system_config_calculate_crc32(&g_system_config);
    }
}

void system_get_config(system_config_t * config)
{
}

/**
 * @brief 读取系统配置
 * @param config: 指向配置结构体的指针
 * @return 0:成功 1:失败
 */
uint8_t system_config_read(system_config_t *config)
{
    uint32_t *flash_ptr = (uint32_t *)SYSTEM_CONFIG_ADDR;
    
    // 读取配置数据
//    config->status = *(system_status_t *)flash_ptr;
//    config->ota_new_app_size = *(flash_ptr + 1);
//    config->current_app_size = *(flash_ptr + 2);
//    config->crc32 = *(flash_ptr + 3);
	
		W25Qx_Read((uint8_t*)config,SYSTEM_CONFIG_ADDR,sizeof(system_config_t));
    
    // 验证CRC
    if (system_config_verify_crc32(config) != 0)
    {
        return 1; // CRC校验失败
    }
    
    return 0; // 读取成功
}

/**
 * @brief 写入系统配置
 * @param config: 指向配置结构体的指针
 * @return 0:成功 1:失败
 */
uint8_t system_config_write(system_config_t *config)
{
    // 计算CRC校验值
    config->crc32 = system_config_calculate_crc32(config);
    
    // 擦除配置扇区

		W25Qx_Erase_Block(SYSTEM_CONFIG_ADDR);
	
    // 写入配置数据 (4个32位字)
    return (W25Qx_Write( (uint8_t *)config,SYSTEM_CONFIG_ADDR,sizeof(system_config_t)) == HAL_OK) ? 0 : 1;
}

/**
 * @brief 设置APP更新状态
 * @param status: APP更新状态
 * @return 0:成功 1:失败
 */
uint8_t system_config_set_app_status(app_update_status_e status)
{
    g_system_config.status.app_update_status = status;
    return system_config_write(&g_system_config);
}

/**
 * @brief 设置OTA新APP大小
 * @param size: OTA新APP大小
 * @return 0:成功 1:失败
 */
uint8_t system_config_set_ota_new_app_size(uint32_t size)
{
    g_system_config.ota_new_app_size = size;
    return system_config_write(&g_system_config);
}

/**
 * @brief 设置当前APP大小
 * @param size: 当前APP大小
 * @return 0:成功 1:失败
 */
uint8_t system_config_set_current_app_size(uint32_t size)
{
    g_system_config.current_app_size = size;
    return system_config_write(&g_system_config);
}

/**
 * @brief 获取APP更新状态
 * @return APP更新状态
 */
app_update_status_e system_config_get_app_status(void)
{
    return (app_update_status_e)g_system_config.status.app_update_status;
}

/**
 * @brief 获取OTA新APP大小
 * @return OTA新APP大小
 */
uint32_t system_config_get_ota_new_app_size(void)
{
    return g_system_config.ota_new_app_size;
}

/**
 * @brief 获取当前APP大小
 * @return 当前APP大小
 */
uint32_t system_config_get_current_app_size(void)
{
    return g_system_config.current_app_size;
}